# coding=utf-8
from datetime import datetime
from flask import Blueprint, g, session, request, redirect, render_template, url_for, abort, jsonify
from uzwan.consts import U_O_GUEST, C_LOGINBACK, U_O_QQ
from uzwan.lib.oauth2 import QQOAuth
from uzwan import db
from uzwan.lib import uuid, get_cookie, del_cookie, account_allow, md5
from uzwan.models.account import AccountGuest, AccountConnect, Account, UserStatus

blueprint = Blueprint('account', __name__)

qq_oauth = QQOAuth()

@blueprint.route('/login')
@account_allow(logined=False)
def login():
    return render_template('login.html')

@blueprint.route('/logout')
@account_allow(logined=True, to='/')
def logout():
    session.pop('user')
    return redirect('/')

@blueprint.route('/guest/create')
@account_allow(logined=False)
def guest_create():
    guest = AccountGuest(uid=uuid(), channel_id=g.channel, register_time=datetime.now(), last_login_time=datetime.now())
    db.session.add(guest)
    db.session.flush()
    session['user'] = UserStatus(guest.id, g.channel, U_O_GUEST, True, True)
    return _redirect_after_login()

@blueprint.route('/guest/complete')
@account_allow(logined=True, guest=True)
def guest_complete():
    return render_template('guest_complete.html', uid=g.user.id)

@blueprint.route('/guest/complete/submit/<account_type>', methods=['POST'])
@account_allow(logined=True, guest=True)
def guest_complete_submit(account_type):
    if account_type != 'mail' or account_type != 'phone':
        abort(404)

    account = request.form['account']
    passwd = request.form['passwd']

    if Account.get_by_account(account):
        return jsonify(code=101, cause=u'用户名已存在')

    account_guest = AccountGuest.get_by_id(g.user.id)
    salt = uuid()
    account = Account(account=account, passwd=_encrypt_passwd(passwd, salt), coins=0, uid=account_guest.uid,
                      register_time=account_guest.register_time, last_login_time=account_guest.last_login_time, origin=U_O_GUEST, channel_id=g.channel, salt=salt)
    db.session.add(account)
    db.session.delete(account_guest)

    return jsonify(code=0, next=get_cookie(request, C_LOGINBACK) or '/')

@blueprint.route('/connect/qq')
@account_allow(logined=False)
def connect_qq():
    return redirect(qq_oauth.get_authorize_url())

@blueprint.route('/connect/qq/callback')
def connect_qq_callback():
    state = request.args['state']
    code = request.args['code']
    access_token, expire_date = qq_oauth.get_access_token(code, state)
    openid = qq_oauth.get_openid(access_token)
    account_connect = AccountConnect.get_by_openid(openid, U_O_QQ)
    if account_connect and account_connect.account.account:
        session['user'] = UserStatus(account_connect.account.id, account_connect.account.channel_id, U_O_QQ, True, False)
        return _redirect_after_login()
    if not account_connect:
        account_connect = AccountConnect(token=access_token, openid=openid, provider=U_O_QQ)
        account = Account(coins=0, uid=uuid(), register_time=datetime.now(), origin=U_O_QQ, channel_id=g.channel, salt=uuid(), connect=account_connect)
        db.session.add(account)
        db.session.flush()
    else:
        account = account_connect.account
    session['user'] = UserStatus(account.id, account.channel_id, U_O_QQ, False, False)
    return redirect(url_for('account.connect_complete', origin_name=u'腾讯QQ', uid=account.id))

@blueprint.route('/connect/complete')
@account_allow(logined=False)
def connect_complete():
    origin_name = request.args['origin_name']
    uid = request.args['uid']
    return render_template('connect_complete.html', origin_name=origin_name, uid=uid)

@blueprint.route('/connect/complete/submit', methods=['POST'])
@account_allow(logined=False)
def connect_complete_submit():
    account_name = request.args['account_name']
    user = g.user
    account = Account.get_by_id(user.id)
    account.account = account_name
    account.last_login_time = datetime.now()
    db.session.add(account)

    user = g.user
    user.logined = True
    session['user'] = user

    return _redirect_after_login()

@blueprint.route('/test')
def test():
    return str(session['user'])

def _redirect_after_login():
    login_back_url = get_cookie(request, C_LOGINBACK) or '/'
    resp = redirect(login_back_url)
    del_cookie(resp, C_LOGINBACK)
    return resp

def _encrypt_passwd(passwd, salt):
    return md5(salt + passwd)